#include "Matrix4x4.h"

namespace Nezha
{

	const Matrix4x4 Matrix4x4::ZERO(0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0);


	const Matrix4x4 Matrix4x4::IDENTITY(1.0, 0.0, 0.0, 0.0,
		0.0, 1.0, 0.0, 0.0,
		0.0, 0.0, 1.0, 0.0,
		0.0, 0.0, 0.0, 1.0);


	Matrix4x4::Matrix4x4(Real f00, Real f01, Real f02, Real f03,
		Real f10, Real f11, Real f12, Real f13,
		Real f20, Real f21, Real f22, Real f23,
		Real f30, Real f31, Real f32, Real f33)
	{
		mEntries[0] = f00;
		mEntries[1] = f01;
		mEntries[2] = f02;
		mEntries[3] = f03;
		mEntries[4] = f10;
		mEntries[5] = f11;
		mEntries[6] = f12;
		mEntries[7] = f13;
		mEntries[8] = f20;
		mEntries[9] = f21;
		mEntries[10] = f22;
		mEntries[11] = f23;
		mEntries[12] = f30;
		mEntries[13] = f31;
		mEntries[14] = f32;
		mEntries[15] = f33;
	}

	Matrix4x4 Matrix4x4::operator +(const Matrix4x4 &mat) const
	{
		return Matrix4x4(
			mEntries[0] + mat.mEntries[0],
			mEntries[1] + mat.mEntries[1],
			mEntries[2] + mat.mEntries[2],
			mEntries[3] + mat.mEntries[3],
			mEntries[4] + mat.mEntries[4],
			mEntries[5] + mat.mEntries[5],
			mEntries[6] + mat.mEntries[6],
			mEntries[7] + mat.mEntries[7],
			mEntries[8] + mat.mEntries[8],
			mEntries[9] + mat.mEntries[9],
			mEntries[10] + mat.mEntries[10],
			mEntries[11] + mat.mEntries[11],
			mEntries[12] + mat.mEntries[12],
			mEntries[13] + mat.mEntries[13],
			mEntries[14] + mat.mEntries[14],
			mEntries[15] + mat.mEntries[15]);
	}

	Matrix4x4 Matrix4x4::operator -(const Matrix4x4 &mat) const
	{
		return Matrix4x4(
			mEntries[0] - mat.mEntries[0],
			mEntries[1] - mat.mEntries[1],
			mEntries[2] - mat.mEntries[2],
			mEntries[3] - mat.mEntries[3],
			mEntries[4] - mat.mEntries[4],
			mEntries[5] - mat.mEntries[5],
			mEntries[6] - mat.mEntries[6],
			mEntries[7] - mat.mEntries[7],
			mEntries[8] - mat.mEntries[8],
			mEntries[9] - mat.mEntries[9],
			mEntries[10] - mat.mEntries[10],
			mEntries[11] - mat.mEntries[11],
			mEntries[12] - mat.mEntries[12],
			mEntries[13] - mat.mEntries[13],
			mEntries[14] - mat.mEntries[14],
			mEntries[15] - mat.mEntries[15]);
	}

	Matrix4x4 Matrix4x4::operator * (const Matrix4x4 &mat) const
	{
		return Matrix4x4(
			mEntries[ 0]*mat.mEntries[ 0] +
			mEntries[ 1]*mat.mEntries[ 4] +
			mEntries[ 2]*mat.mEntries[ 8] +
			mEntries[ 3]*mat.mEntries[12],

			mEntries[ 0]*mat.mEntries[ 1] +
			mEntries[ 1]*mat.mEntries[ 5] +
			mEntries[ 2]*mat.mEntries[ 9] +
			mEntries[ 3]*mat.mEntries[13],

			mEntries[ 0]*mat.mEntries[ 2] +
			mEntries[ 1]*mat.mEntries[ 6] +
			mEntries[ 2]*mat.mEntries[10] +
			mEntries[ 3]*mat.mEntries[14],

			mEntries[ 0]*mat.mEntries[ 3] +
			mEntries[ 1]*mat.mEntries[ 7] +
			mEntries[ 2]*mat.mEntries[11] +
			mEntries[ 3]*mat.mEntries[15],

			mEntries[ 4]*mat.mEntries[ 0] +
			mEntries[ 5]*mat.mEntries[ 4] +
			mEntries[ 6]*mat.mEntries[ 8] +
			mEntries[ 7]*mat.mEntries[12],

			mEntries[ 4]*mat.mEntries[ 1] +
			mEntries[ 5]*mat.mEntries[ 5] +
			mEntries[ 6]*mat.mEntries[ 9] +
			mEntries[ 7]*mat.mEntries[13],

			mEntries[ 4]*mat.mEntries[ 2] +
			mEntries[ 5]*mat.mEntries[ 6] +
			mEntries[ 6]*mat.mEntries[10] +
			mEntries[ 7]*mat.mEntries[14],

			mEntries[ 4]*mat.mEntries[ 3] +
			mEntries[ 5]*mat.mEntries[ 7] +
			mEntries[ 6]*mat.mEntries[11] +
			mEntries[ 7]*mat.mEntries[15],

			mEntries[ 8]*mat.mEntries[ 0] +
			mEntries[ 9]*mat.mEntries[ 4] +
			mEntries[10]*mat.mEntries[ 8] +
			mEntries[11]*mat.mEntries[12],

			mEntries[ 8]*mat.mEntries[ 1] +
			mEntries[ 9]*mat.mEntries[ 5] +
			mEntries[10]*mat.mEntries[ 9] +
			mEntries[11]*mat.mEntries[13],

			mEntries[ 8]*mat.mEntries[ 2] +
			mEntries[ 9]*mat.mEntries[ 6] +
			mEntries[10]*mat.mEntries[10] +
			mEntries[11]*mat.mEntries[14],

			mEntries[ 8]*mat.mEntries[ 3] +
			mEntries[ 9]*mat.mEntries[ 7] +
			mEntries[10]*mat.mEntries[11] +
			mEntries[11]*mat.mEntries[15],

			mEntries[12]*mat.mEntries[ 0] +
			mEntries[13]*mat.mEntries[ 4] +
			mEntries[14]*mat.mEntries[ 8] +
			mEntries[15]*mat.mEntries[12],

			mEntries[12]*mat.mEntries[ 1] +
			mEntries[13]*mat.mEntries[ 5] +
			mEntries[14]*mat.mEntries[ 9] +
			mEntries[15]*mat.mEntries[13],

			mEntries[12]*mat.mEntries[ 2] +
			mEntries[13]*mat.mEntries[ 6] +
			mEntries[14]*mat.mEntries[10] +
			mEntries[15]*mat.mEntries[14],

			mEntries[12]*mat.mEntries[ 3] +
			mEntries[13]*mat.mEntries[ 7] +
			mEntries[14]*mat.mEntries[11] +
			mEntries[15]*mat.mEntries[15]);
	}

	Matrix4x4 Matrix4x4::operator * (Real fScalar) const
	{
		return Matrix4x4(
			fScalar * mEntries[0],
			fScalar * mEntries[1],
			fScalar * mEntries[2],
			fScalar * mEntries[3],
			fScalar * mEntries[4],
			fScalar * mEntries[5],
			fScalar * mEntries[6],
			fScalar * mEntries[7],
			fScalar * mEntries[8],
			fScalar * mEntries[9],
			fScalar * mEntries[10],
			fScalar * mEntries[11],
			fScalar * mEntries[12],
			fScalar * mEntries[13],
			fScalar * mEntries[14],
			fScalar * mEntries[15]);
	}

	Matrix4x4 Matrix4x4::operator / (Real fScalar) const
	{
		if(fScalar != 0.0)
		{
			fScalar = (Real)1.0 / fScalar;
			return Matrix4x4(
				fScalar * mEntries[0],
				fScalar * mEntries[1],
				fScalar * mEntries[2],
				fScalar * mEntries[3],
				fScalar * mEntries[4],
				fScalar * mEntries[5],
				fScalar * mEntries[6],
				fScalar * mEntries[7],
				fScalar * mEntries[8],
				fScalar * mEntries[9],
				fScalar * mEntries[10],
				fScalar * mEntries[11],
				fScalar * mEntries[12],
				fScalar * mEntries[13],
				fScalar * mEntries[14],
				fScalar * mEntries[15]);
		}

		return Matrix4x4(
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY,
			NZ_INFINITY);
	}

	Matrix4x4 Matrix4x4::operator - () const
	{
		return Matrix4x4(
			-mEntries[0],
			-mEntries[1],
			-mEntries[2],
			-mEntries[3],
			-mEntries[4],
			-mEntries[5],
			-mEntries[6],
			-mEntries[7],
			-mEntries[8],
			-mEntries[9],
			-mEntries[10],
			-mEntries[11],
			-mEntries[12],
			-mEntries[13],
			-mEntries[14],
			-mEntries[15]);
	}

	Matrix4x4& Matrix4x4::operator += (const Matrix4x4 &mat)
	{
		mEntries[0] += mat.mEntries[0];
		mEntries[1] += mat.mEntries[1];
		mEntries[2] += mat.mEntries[2];
		mEntries[3] += mat.mEntries[3];
		mEntries[4] += mat.mEntries[4];
		mEntries[5] += mat.mEntries[5];
		mEntries[6] += mat.mEntries[6];
		mEntries[7] += mat.mEntries[7];
		mEntries[8] += mat.mEntries[8];
		mEntries[9] += mat.mEntries[9];
		mEntries[10] += mat.mEntries[10];
		mEntries[11] += mat.mEntries[11];
		mEntries[12] += mat.mEntries[12];
		mEntries[13] += mat.mEntries[13];
		mEntries[14] += mat.mEntries[14];
		mEntries[15] += mat.mEntries[15];

		return *this;
	}

	Matrix4x4& Matrix4x4::operator -=(const Matrix4x4 &mat)
	{
		mEntries[0] -= mat.mEntries[0];
		mEntries[1] -= mat.mEntries[1];
		mEntries[2] -= mat.mEntries[2];
		mEntries[3] -= mat.mEntries[3];
		mEntries[4] -= mat.mEntries[4];
		mEntries[5] -= mat.mEntries[5];
		mEntries[6] -= mat.mEntries[6];
		mEntries[7] -= mat.mEntries[7];
		mEntries[8] -= mat.mEntries[8];
		mEntries[9] -= mat.mEntries[9];
		mEntries[10] -= mat.mEntries[10];
		mEntries[11] -= mat.mEntries[11];
		mEntries[12] -= mat.mEntries[12];
		mEntries[13] -= mat.mEntries[13];
		mEntries[14] -= mat.mEntries[14];
		mEntries[15] -= mat.mEntries[15];

		return *this;
	}

	Matrix4x4& Matrix4x4::operator*= (Real fScalar)
	{
		mEntries[0] *= fScalar;
		mEntries[1] *= fScalar;
		mEntries[2] *= fScalar;
		mEntries[3] *= fScalar;
		mEntries[4] *= fScalar;
		mEntries[5] *= fScalar;
		mEntries[6] *= fScalar;
		mEntries[7] *= fScalar;
		mEntries[8] *= fScalar;
		mEntries[9] *= fScalar;
		mEntries[10] *= fScalar;
		mEntries[11] *= fScalar;
		mEntries[12] *= fScalar;
		mEntries[13] *= fScalar;
		mEntries[14] *= fScalar;
		mEntries[15] *= fScalar;

		return *this;
	}

	Matrix4x4& Matrix4x4::operator /=(Real fScalar)
	{
		if (fScalar != (Real)0.0)
		{
			Real fInvScalar = ((Real)1.0)/fScalar;
			mEntries[ 0] *= fInvScalar;
			mEntries[ 1] *= fInvScalar;
			mEntries[ 2] *= fInvScalar;
			mEntries[ 3] *= fInvScalar;
			mEntries[ 4] *= fInvScalar;
			mEntries[ 5] *= fInvScalar;
			mEntries[ 6] *= fInvScalar;
			mEntries[ 7] *= fInvScalar;
			mEntries[ 8] *= fInvScalar;
			mEntries[ 9] *= fInvScalar;
			mEntries[10] *= fInvScalar;
			mEntries[11] *= fInvScalar;
			mEntries[12] *= fInvScalar;
			mEntries[13] *= fInvScalar;
			mEntries[14] *= fInvScalar;
			mEntries[15] *= fInvScalar;
		}
		else
		{
			mEntries[ 0] = NZ_INFINITY;
			mEntries[ 1] = NZ_INFINITY;
			mEntries[ 2] = NZ_INFINITY;
			mEntries[ 3] = NZ_INFINITY;
			mEntries[ 4] = NZ_INFINITY;
			mEntries[ 5] = NZ_INFINITY;
			mEntries[ 6] = NZ_INFINITY;
			mEntries[ 7] = NZ_INFINITY;
			mEntries[ 8] = NZ_INFINITY;
			mEntries[ 9] = NZ_INFINITY;
			mEntries[10] = NZ_INFINITY;
			mEntries[11] = NZ_INFINITY;
			mEntries[12] = NZ_INFINITY;
			mEntries[13] = NZ_INFINITY;
			mEntries[14] = NZ_INFINITY;
			mEntries[15] = NZ_INFINITY;
		}

		return *this;
	}

	Vector4 Matrix4x4::operator * (const Vector4 &v) const
	{
		return Vector4(
			mEntries[0] * v.x +
			mEntries[1] * v.y +
			mEntries[2] * v.z + 
			mEntries[3] * v.w,

			mEntries[4] * v.x +
			mEntries[5] * v.y +
			mEntries[6] * v.z + 
			mEntries[7] * v.w,

			mEntries[8] * v.x +
			mEntries[9] * v.y +
			mEntries[10] * v.z + 
			mEntries[11] * v.w,

			mEntries[12] * v.x +
			mEntries[13] * v.y +
			mEntries[14] * v.z + 
			mEntries[15] * v.w);
	}

	Matrix4x4 Matrix4x4::transpose() const
	{
		return Matrix4x4(
			mEntries[0],
			mEntries[4],
			mEntries[8],
			mEntries[12],
			mEntries[1],
			mEntries[5],
			mEntries[9],
			mEntries[13],
			mEntries[2],
			mEntries[6],
			mEntries[10],
			mEntries[14],
			mEntries[3],
			mEntries[7],
			mEntries[11],
			mEntries[15]);
	}

	Matrix4x4 Matrix4x4::transposeTimes(const Matrix4x4 &mat) const
	{
		return Matrix4x4(
			mEntries[ 0]*mat.mEntries[ 0] +
			mEntries[ 4]*mat.mEntries[ 4] +
			mEntries[ 8]*mat.mEntries[ 8] +
			mEntries[12]*mat.mEntries[12],

			mEntries[ 0]*mat.mEntries[ 1] +
			mEntries[ 4]*mat.mEntries[ 5] +
			mEntries[ 8]*mat.mEntries[ 9] +
			mEntries[12]*mat.mEntries[13],

			mEntries[ 0]*mat.mEntries[ 2] +
			mEntries[ 4]*mat.mEntries[ 6] +
			mEntries[ 8]*mat.mEntries[10] +
			mEntries[12]*mat.mEntries[14],

			mEntries[ 0]*mat.mEntries[ 3] +
			mEntries[ 4]*mat.mEntries[ 7] +
			mEntries[ 8]*mat.mEntries[11] +
			mEntries[12]*mat.mEntries[15],

			mEntries[ 1]*mat.mEntries[ 0] +
			mEntries[ 5]*mat.mEntries[ 4] +
			mEntries[ 9]*mat.mEntries[ 8] +
			mEntries[13]*mat.mEntries[12],

			mEntries[ 1]*mat.mEntries[ 1] +
			mEntries[ 5]*mat.mEntries[ 5] +
			mEntries[ 9]*mat.mEntries[ 9] +
			mEntries[13]*mat.mEntries[13],

			mEntries[ 1]*mat.mEntries[ 2] +
			mEntries[ 5]*mat.mEntries[ 6] +
			mEntries[ 9]*mat.mEntries[10] +
			mEntries[13]*mat.mEntries[14],

			mEntries[ 1]*mat.mEntries[ 3] +
			mEntries[ 5]*mat.mEntries[ 7] +
			mEntries[ 9]*mat.mEntries[11] +
			mEntries[13]*mat.mEntries[15],

			mEntries[ 2]*mat.mEntries[ 0] +
			mEntries[ 6]*mat.mEntries[ 4] +
			mEntries[10]*mat.mEntries[ 8] +
			mEntries[14]*mat.mEntries[12],

			mEntries[ 2]*mat.mEntries[ 1] +
			mEntries[ 6]*mat.mEntries[ 5] +
			mEntries[10]*mat.mEntries[ 9] +
			mEntries[14]*mat.mEntries[13],

			mEntries[ 2]*mat.mEntries[ 2] +
			mEntries[ 6]*mat.mEntries[ 6] +
			mEntries[10]*mat.mEntries[10] +
			mEntries[14]*mat.mEntries[14],

			mEntries[ 2]*mat.mEntries[ 3] +
			mEntries[ 6]*mat.mEntries[ 7] +
			mEntries[10]*mat.mEntries[11] +
			mEntries[14]*mat.mEntries[15],

			mEntries[ 3]*mat.mEntries[ 0] +
			mEntries[ 7]*mat.mEntries[ 4] +
			mEntries[11]*mat.mEntries[ 8] +
			mEntries[15]*mat.mEntries[12],

			mEntries[ 3]*mat.mEntries[ 1] +
			mEntries[ 7]*mat.mEntries[ 5] +
			mEntries[11]*mat.mEntries[ 9] +
			mEntries[15]*mat.mEntries[13],

			mEntries[ 3]*mat.mEntries[ 2] +
			mEntries[ 7]*mat.mEntries[ 6] +
			mEntries[11]*mat.mEntries[10] +
			mEntries[15]*mat.mEntries[14],

			mEntries[ 3]*mat.mEntries[ 3] +
			mEntries[ 7]*mat.mEntries[ 7] +
			mEntries[11]*mat.mEntries[11] +
			mEntries[15]*mat.mEntries[15]);
	}

	Matrix4x4 Matrix4x4::timesDiagonal(const Vector4&diag) const
	{
		return Matrix4x4(
			mEntries[0]*diag.x, mEntries[1]*diag.y, mEntries[2]*diag.z, mEntries[3]*diag.w,
			mEntries[4]*diag.x, mEntries[5]*diag.y, mEntries[6]*diag.z, mEntries[7]*diag.w,
			mEntries[8]*diag.x, mEntries[9]*diag.y, mEntries[10]*diag.z, mEntries[11]*diag.w,
			mEntries[12]*diag.x, mEntries[13]*diag.y, mEntries[14]*diag.z, mEntries[15]*diag.w);
	}

	Matrix4x4 Matrix4x4::inverse() const
	{
		Real fA0 = mEntries[ 0]*mEntries[ 5] - mEntries[ 1]*mEntries[ 4];
		Real fA1 = mEntries[ 0]*mEntries[ 6] - mEntries[ 2]*mEntries[ 4];
		Real fA2 = mEntries[ 0]*mEntries[ 7] - mEntries[ 3]*mEntries[ 4];
		Real fA3 = mEntries[ 1]*mEntries[ 6] - mEntries[ 2]*mEntries[ 5];
		Real fA4 = mEntries[ 1]*mEntries[ 7] - mEntries[ 3]*mEntries[ 5];
		Real fA5 = mEntries[ 2]*mEntries[ 7] - mEntries[ 3]*mEntries[ 6];
		Real fB0 = mEntries[ 8]*mEntries[13] - mEntries[ 9]*mEntries[12];
		Real fB1 = mEntries[ 8]*mEntries[14] - mEntries[10]*mEntries[12];
		Real fB2 = mEntries[ 8]*mEntries[15] - mEntries[11]*mEntries[12];
		Real fB3 = mEntries[ 9]*mEntries[14] - mEntries[10]*mEntries[13];
		Real fB4 = mEntries[ 9]*mEntries[15] - mEntries[11]*mEntries[13];
		Real fB5 = mEntries[10]*mEntries[15] - mEntries[11]*mEntries[14];

		Real fDet = fA0*fB5-fA1*fB4+fA2*fB3+fA3*fB2-fA4*fB1+fA5*fB0;
		if(fabs(fDet) <= NZ_TOLERANCE)
		{
			return Matrix4x4::ZERO;
		}

		Matrix4x4 mInv;
		mInv.mEntries[ 0] =
			+ mEntries[ 5]*fB5 - mEntries[ 6]*fB4 + mEntries[ 7]*fB3;
		mInv.mEntries[ 4] =
			- mEntries[ 4]*fB5 + mEntries[ 6]*fB2 - mEntries[ 7]*fB1;
		mInv.mEntries[ 8] =
			+ mEntries[ 4]*fB4 - mEntries[ 5]*fB2 + mEntries[ 7]*fB0;
		mInv.mEntries[12] =
			- mEntries[ 4]*fB3 + mEntries[ 5]*fB1 - mEntries[ 6]*fB0;
		mInv.mEntries[ 1] =
			- mEntries[ 1]*fB5 + mEntries[ 2]*fB4 - mEntries[ 3]*fB3;
		mInv.mEntries[ 5] =
			+ mEntries[ 0]*fB5 - mEntries[ 2]*fB2 + mEntries[ 3]*fB1;
		mInv.mEntries[ 9] =
			- mEntries[ 0]*fB4 + mEntries[ 1]*fB2 - mEntries[ 3]*fB0;
		mInv.mEntries[13] =
			+ mEntries[ 0]*fB3 - mEntries[ 1]*fB1 + mEntries[ 2]*fB0;
		mInv.mEntries[ 2] =
			+ mEntries[13]*fA5 - mEntries[14]*fA4 + mEntries[15]*fA3;
		mInv.mEntries[ 6] =
			- mEntries[12]*fA5 + mEntries[14]*fA2 - mEntries[15]*fA1;
		mInv.mEntries[10] =
			+ mEntries[12]*fA4 - mEntries[13]*fA2 + mEntries[15]*fA0;
		mInv.mEntries[14] =
			- mEntries[12]*fA3 + mEntries[13]*fA1 - mEntries[14]*fA0;
		mInv.mEntries[ 3] =
			- mEntries[ 9]*fA5 + mEntries[10]*fA4 - mEntries[11]*fA3;
		mInv.mEntries[ 7] =
			+ mEntries[ 8]*fA5 - mEntries[10]*fA2 + mEntries[11]*fA1;
		mInv.mEntries[11] =
			- mEntries[ 8]*fA4 + mEntries[ 9]*fA2 - mEntries[11]*fA0;
		mInv.mEntries[15] =
			+ mEntries[ 8]*fA3 - mEntries[ 9]*fA1 + mEntries[10]*fA0;

		Real fInvDet = (Real)1.0 / fDet;

		mInv.mEntries[ 0] *= fInvDet;
		mInv.mEntries[ 1] *= fInvDet;
		mInv.mEntries[ 2] *= fInvDet;
		mInv.mEntries[ 3] *= fInvDet;
		mInv.mEntries[ 4] *= fInvDet;
		mInv.mEntries[ 5] *= fInvDet;
		mInv.mEntries[ 6] *= fInvDet;
		mInv.mEntries[ 7] *= fInvDet;
		mInv.mEntries[ 8] *= fInvDet;
		mInv.mEntries[ 9] *= fInvDet;
		mInv.mEntries[10] *= fInvDet;
		mInv.mEntries[11] *= fInvDet;
		mInv.mEntries[12] *= fInvDet;
		mInv.mEntries[13] *= fInvDet;
		mInv.mEntries[14] *= fInvDet;
		mInv.mEntries[15] *= fInvDet;

		return mInv;
	}

	Real Matrix4x4::determiant() const
	{
		Real fA0 = mEntries[ 0]*mEntries[ 5] - mEntries[ 1]*mEntries[ 4];
		Real fA1 = mEntries[ 0]*mEntries[ 6] - mEntries[ 2]*mEntries[ 4];
		Real fA2 = mEntries[ 0]*mEntries[ 7] - mEntries[ 3]*mEntries[ 4];
		Real fA3 = mEntries[ 1]*mEntries[ 6] - mEntries[ 2]*mEntries[ 5];
		Real fA4 = mEntries[ 1]*mEntries[ 7] - mEntries[ 3]*mEntries[ 5];
		Real fA5 = mEntries[ 2]*mEntries[ 7] - mEntries[ 3]*mEntries[ 6];
		Real fB0 = mEntries[ 8]*mEntries[13] - mEntries[ 9]*mEntries[12];
		Real fB1 = mEntries[ 8]*mEntries[14] - mEntries[10]*mEntries[12];
		Real fB2 = mEntries[ 8]*mEntries[15] - mEntries[11]*mEntries[12];
		Real fB3 = mEntries[ 9]*mEntries[14] - mEntries[10]*mEntries[13];
		Real fB4 = mEntries[ 9]*mEntries[15] - mEntries[11]*mEntries[13];
		Real fB5 = mEntries[10]*mEntries[15] - mEntries[11]*mEntries[14];
		Real fDet = fA0*fB5-fA1*fB4+fA2*fB3+fA3*fB2-fA4*fB1+fA5*fB0;
		return fDet;
	}

}//end namespace Nezha